import React, { useState, useMemo } from 'react'

//函数组件首字符必须大写 创建和使用组件的时候一样
/* 
函数组件的形参=props属性 = 父传来的数据

hooks组件？
react16.8以后新增hook功能
函数组件的加强使用 在不使用类组件的前提下 函数组件可以使用状态 使用周期等特性

函数组件和类组件的区别
1.类组件属于面向对象编程 有类 有实例 有继承 有状态 有周期
2.函数组件属于函数式编程 无状态 无周期 无this
3.对比起类组件 函数组件没有实例化过程 渲染速度更快

hook使用原则？
1.只能在函数组件中使用hook
2.只能在函数组件顶层使用hook
3.不能在if for 事件函数中嵌套hook

常用hook有那些? (内置 react提供的)
1.useState：使用状态
2.useContext：使用上下文
3.useMemo：缓存属性 计算属性
4.useReducer：状态管理，替代useState
5.useCallback：缓存方法
6.useRef：获取dom
7.useEffect:副作用钩子 实现生命周期

useState使用？
useState执行，返回一个数组 数组第一项状态名称 第二项修改状态的方法
*/

export default function HookState(props) {

    //console.log(props);
    let [n, setN] = useState(10)
    let [m, setM] = useState(100)
    let [state, setState] = useState({
        name: 'xxx',
        age: 10
    })
    let [list, setList] = useState([
        { id: 1, title: '西瓜', price: 1.5, sed: false },
        { id: 2, title: '葡萄', price: 3.5, sed: true },
        { id: 3, title: '西红柿', price: 2.5, sed: false }
    ])
    //获取到输入框的值
    let [title, setTitle] = useState('')

    //添加方法
    let Add = () => {
        let obj = {
            id: new Date().getTime(),
            title,
            price: 1.5,
            sed: false
        }
        setList([obj, ...list])
        setTitle('')
    }

    //删除方法
    let del = (id) => {
        let newlist = list.filter(item => {
            return item.id !== id
        })
        setList(newlist)
    }

    //切换数组中的sed属性
    let changeSed = (id) => {
        let newlist = [...list]
        newlist.forEach(item => {
            if (item.id == id) {
                item.sed = !item.sed
            }
        })
        setList(newlist)
    }

    //缓存属性 === 计算属性 2个参数 回调函数计算结果 依赖值的数组
    //计算出上架的个数
    let sedT = useMemo(() => {
        return list.reduce((p, n) => {
            if (n.sed) {
                return p + 1
            }
            return p
        }, 0)
    }, [list])

    //全选 反选
    let all = useMemo(() => {
        return list.every(item => {
            return item.sed
        })
    }, [list])
    let allSed = (c) => {
        let newlist = [...list]
        newlist.forEach(item => {
            item.sed = c
        })    
        setList(newlist)
    }


    return (
        <div>
            <h2>函数组件</h2>
            <div>
                <p>{n}</p>
                <button onClick={() => {
                    setN(n + 1)
                }}>修改n</button>
                <p>{m}</p>
                <button onClick={() => {
                    setM(m + 1)
                }}>修改m</button>
                <p>名称:{state.name} 年龄:{state.age}</p>
                <button onClick={() => {
                    /* 
                    class(类组件)中的setState(函数组件)和hook中的setState异同
                    相同点:都是异步的 
                    不同:类组件的setState合并式修改 函数组件setState替换式修改
                    this.setState({n:this.state.n+1})
                    objeact.assqin({n:1,m:20},{n:this.state.n+1})
                    */
                    setState({ ...state, age: state.age + 1 })
                }}>修改年龄</button>
            </div>
            <div>
                {/* 表单的属性和状态绑定 表单onchange的时候 获取到输入的值 再去修改状态 */}
                <input value={title} onChange={(e) => {
                    //console.log(e)    
                    setTitle(e.target.value)
                }} /><button onClick={() => {
                    Add()
                }}>添加商品</button>
            </div>
            <div>
                全选:<input type='checkbox' checked={all} onChange={(e) => {
                    allSed(e.target.checked)
                 }} />
            </div>
            {
                list.map(item => {
                    return <div key={item.id}>
                        <input type='checkbox' checked={item.sed} onChange={() => {
                            changeSed(item.id)
                        }} />
                        <span>商品名称:{item.title}</span>
                        <span>商品价格:{item.price}</span>
                        <button onClick={() => {
                            changeSed(item.id)
                        }}>{item.sed ? '上架' : '下架'}</button>
                        <button onClick={() => { del(item.id) }}>删除</button>
                    </div>
                })
            }
            <div>数量:{sedT}</div>
        </div>
    )
}
